/*******************************************************************************************
* Copyright (C) 2026 PACIFICO PAUL
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* 
********************************************************************************************/

package library;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.util.Locale;

import javax.swing.JOptionPane;

import application.Console;
import application.Shutter;
import application.Update;
import application.Utils;

public class DEOLDIFY extends Shutter {
	
	public static Thread runProcess;
	public static Process process;
	private static File deoldifyFolder = new File(documents.toString() + "/Library/deoldify");
	private static File deoldify;
	public static boolean error = false;
	public static boolean isRunning = false;
	
	public static String deoldifyModel;
	public static String modelLink = "";	
	public static String modelName;
	public static long modelSize;

	public static void checkDeoldify() {
		
		if (System.getProperty("os.name").contains("Windows"))
		{
			deoldify = new File(deoldifyFolder.toString() + "/deoldify");
		}
		else
			deoldify = new File(deoldifyFolder.toString() + "/lib/python3.10/site-packages/deoldify");	
			
		if (deoldify.exists() == false)
		{		
			int q =  JOptionPane.showConfirmDialog(Shutter.frame, Shutter.language.getProperty("additionalFiles") + System.lineSeparator() + Shutter.language.getProperty("wantToDownload"), Shutter.language.getProperty("functionSeparation"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);	    						 
			if (q == JOptionPane.YES_OPTION)
			{	    									
				if (System.getProperty("os.name").contains("Windows"))
				{
					String[] cmd = { deoldifyFolder.toString() + "/python.exe", "-m", "pip", "install", "deoldify", "--only-binary=opencv-python", "matplotlib", "numpy==1.25.2", "pandas", "scipy", "fastprogress", "torch==2.3.0", "torchvision", "torchaudio", "--target", deoldifyFolder.toString(), "--no-warn-script-location" };
					PYTHON.installModule(deoldifyFolder, cmd, deoldify);						 	
				}
				else
				{
					String[] cmd = { deoldifyFolder.toString() + "/bin/python3", "-m", "pip", "install", "deoldify", "--only-binary=opencv-python", "matplotlib", "pandas", "scipy", "fastprogress", "torch==2.3.0", "torchvision", "torchaudio", "--no-warn-script-location" };
					
					if (System.getProperty("os.name").contains("Mac") && arch.equals("x86_64"))
					{
						cmd = new String[] { deoldifyFolder.toString() + "/bin/python3", "-m", "pip", "install", "deoldify", "--only-binary=opencv-python", "matplotlib", "numpy==1.25.2", "pandas", "scipy", "fastprogress", "torch==2.3.0", "torchvision", "torchaudio", "--no-warn-script-location" };
					}
					
					PYTHON.installModule(deoldifyFolder, cmd, deoldify);			
				}
			}
			else
				comboFonctions.setSelectedItem("");			
		}
	}
	
    public static void downloadModel() {
		        
    	switch (comboFilter.getSelectedIndex())
		{	
			case 0: //Artistic
				
				modelLink = "https://huggingface.co/databuzzword/deoldify-artistic/resolve/aae6daa766bab0496224bf01a4b7959941703bce/ColorizeArtistic_gen.pth?download=true";
				modelName = "ColorizeArtistic_gen.pth";
				modelSize = 255144681L;	
				break;
			
			case 1: //Stable
				
				modelLink = "https://huggingface.co/spensercai/DeOldify/resolve/main/ColorizeStable_gen.pth?download=true";
				modelName = "ColorizeStable_gen.pth";
				modelSize = 874066230L;			
				break;
				
			case 2: //Video
				
				modelLink = "https://huggingface.co/spensercai/DeOldify/resolve/main/ColorizeVideo_gen.pth?download=true";
				modelName = "ColorizeVideo_gen.pth";
				modelSize = 874066230L;
				break;
			
		}      
    	
    	deoldifyModel = deoldifyFolder.toString() + "/models/" + modelName;
    	
		File model = new File(deoldifyModel);
		File modelPath = new File(model.getParent());
				
		if (modelPath.exists() == false)
		{
			modelPath.mkdir();
		}
		
		try {
			if (model.exists() && Files.size(model.toPath()) != modelSize)				
			{
				model.delete();
			}
		} catch (IOException e1) {}
		
		if (model.exists() == false)
		{
			new Update();
			
			if (Shutter.getLanguage.contains(Locale.of("ar").getDisplayLanguage()))
			{
				Update.lblNewVersion.setText(Shutter.language.getProperty("downloadingAIModel") + " 1/2");
			}
			else
				Update.lblNewVersion.setText(Shutter.language.getProperty("downloadingAIModel") + " 1/2");
			
			Utils.changeFrameVisibility(Shutter.frame, true);
			
			Update.HTTPDownload(modelLink, deoldifyModel);	

			Utils.changeFrameVisibility(Shutter.frame, false);
			Shutter.frame.toFront();
			
			Update.frame.dispose();
			
			if (model.exists() == false && Shutter.comboFonctions.getSelectedItem().equals(Shutter.language.getProperty("functionColorize")))
			{
				Shutter.comboFonctions.setSelectedItem("");;
			}
		}
		
	}   
	
	public static void run(String file, String model, String output) {
		
		disableAll();
		error = false;
		progressBar1.setValue(0);
		progressBar1.setMaximum(100);
		btnStart.setEnabled(false);
		
		runProcess = new Thread(new Runnable() {	
			
			@Override
			public void run() {
					
				try {		
					
					//Copy colorize.py to allow writing into models folder
					File colorizeSource = new File(new File(FFMPEG.PathToFFMPEG.replace("\\ ", " ")).getParent() + "/colorize.py");
					File colorizePath = new File(deoldifyFolder.toString() + "/colorize.py");
					if (colorizePath.exists() == false)
					{
						Files.copy(colorizeSource.toPath(), colorizePath.toPath());
					}
										
					ProcessBuilder processBuilder;
					if (System.getProperty("os.name").contains("Windows"))
					{
						processBuilder = new ProcessBuilder(deoldifyFolder.toString() + "/python.exe", colorizePath.toString(), file, "-m", model, "-o", output);
					}
					else
						processBuilder = new ProcessBuilder(deoldifyFolder.toString() + "/bin/python3", colorizePath.toString(), file, "-m", model, "-o", output);
					
					processBuilder.directory(deoldifyFolder);
					processBuilder.redirectErrorStream(true);
					 
					Console.consolePYTHON.append(language.getProperty("command") + " python3 " + colorizePath + " " + file + " -m " + model + " -o " + output);	
					
					isRunning = true;	
					process = processBuilder.start();
		            
		            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
		            
		            Console.consolePYTHON.append(System.lineSeparator());
							            		            
		            String line;
		            boolean downloadModel = false;
		            while ((line = reader.readLine()) != null)
		            {		            			            	
		            	if (line.contains("RuntimeError") || line.contains("cannot identify image file"))
		            		error = true;		
		            	
		            	if (line.contains("Downloading:"))
		            		downloadModel = true;		            	
		            	
		            	if (downloadModel)
		            	{
		            		if (progressBar1.getValue() == progressBar1.getMaximum())
		            		{
		            			downloadModel = false;
		            			progressBar1.setValue(0);
		            			lblCurrentEncoding.setText(new File(file).getName());
		            		}
		            		else
		            			lblCurrentEncoding.setText(language.getProperty("downloadingAIModel") + " 2/2");		
		            	}
		            	
		            	if (downloadModel && line.contains("%"))
		            	{
		            		String s[] = line.split("\\.");
		            		progressBar1.setValue(Integer.valueOf(s[0].replace(" ","")));
		            	} 
		            	else if (line.contains("Done!"))
		            	{
		            		progressBar1.setValue(100);
		            	}
		            	
		            	if (cancelled)
		            		break;
		            	
		                Console.consolePYTHON.append(line + System.lineSeparator());
		            }
		            
		            process.waitFor();
		            
		            Console.consolePYTHON.append(System.lineSeparator());
					
					isRunning = false;	    
		            
				} catch (Exception e) {
					error = true;
					e.printStackTrace();
				}
				finally {
					enableAll();
				}
			}
			
		});
		runProcess.start();
	}
}